﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using FlickrXplorer.Web.ViewData;
using Linq.Flickr;
using LinqExtender;
using log4net;
using Microsoft.Practices.EnterpriseLibrary.Caching;
using Microsoft.Practices.EnterpriseLibrary.Caching.Expirations;
using People=FlickrXplorer.Web.ViewData.People;

namespace FlickrXplorer.Web.Models
{
    public class CommentModel : ICommentModel
    {
        private readonly FlickrContext context = null;
        private readonly ILog log = LogManager.GetLogger("CommentModel");
        private ICacheManager privateCache;
        public CommentModel()
        {
            privateCache = CacheFactory.GetCacheManager();
            context = new FlickrContext();
            context.Photos.Comments.OnError += new LinqExtender.Query<Comment>.ErrorHandler(ShowException);
        }
     
        private void ShowException (ProviderException ex)
        {
            log.Error("Error processing comment", ex);
            // throw.
            throw new Exception(ex.Message);
        }

        public PhotoCommentViewData GetComments(string photoid, int index, int pageLen, bool invalidateCache)
        {
            string cacheKey = MethodBase.GetCurrentMethod().Name + photoid;
            object obj = privateCache.GetData(cacheKey);

            PhotoCommentViewData commentViewData = new PhotoCommentViewData();
            IEnumerable<PhotoComment> cm;

            if (obj == null || invalidateCache)
            {
                var query = from comment in context.Photos.Comments
                            where comment.PhotoId == photoid
                            select new PhotoComment
                                       {
                                           Text =
                                               System.Text.RegularExpressions.Regex.Replace(comment.Text, @"<img[^>]*>",
                                                                                            string.Empty),
                                           PhotoId = comment.PhotoId,
                                           AuthorName = comment.AuthorName,
                                           PermaLink = comment.PermaLink,
                                           Author = comment.Author,
                                           Id = comment.Id
                                       };

               cm = query;
                // cache it for 12 hours.
               privateCache.Add(cacheKey, cm, CacheItemPriority.Normal, null, new SlidingTime(TimeSpan.FromHours(12)));
            }
            else
            {
                cm = obj as IEnumerable<PhotoComment>;
            }

            commentViewData.Total = cm.Count();
            if (context.IsAuthenticated())
            {
                commentViewData.UserId = context.Authenticate().UserId;
            }
            commentViewData.IsAuthenticated = context.IsAuthenticated();
            commentViewData.Comments = cm.Skip(index).Take(pageLen);

            return commentViewData;
        }

        public bool AddCommment(string text, string photoId)
        {
            Comment comment = new Comment {PhotoId = photoId, Text = text};

            context.Photos.Comments.Add(comment);
            context.Photos.Comments.SubmitChanges();

            if (privateCache.Contains("GetComments" + photoId))
            {
                privateCache.Remove("GetComments" + photoId);
            }

            return (!string.IsNullOrEmpty(comment.Id));   
        }

        public void Authenticated()
        {
            context.Authenticate();
        }

        public bool DeleteComment(string commetId, string photoId)
        {
            Comment comment = context.Photos.Comments.Where(c => c.Id == commetId && c.PhotoId == photoId).Single();
            context.Photos.Comments.Remove(comment);
            context.SubmitChanges();

            if (privateCache.Contains("GetComments" + photoId))
            {
                privateCache.Remove("GetComments" + photoId);
            }

            return true;
        }
    }
}
